import React,{useState,useEffect} from 'react'
// useEffect
// 作用：钩住组件中某些生命周期函数(componentDidMount(组件被挂载完成后)、componentDidUpdate(组件重新渲染完成后)、
// componentWillUnmount(组件即将被卸载前))
// 解决类组件某些执行代码被分散在不同的生命周期函数的问题
// 基本用法
// useEffect(effect,[deps])函数可以传入2个参数，第一个参数为定义的执行函数，第2个参数是依赖关系(可选参数)
// 若一个函数组件中定义了多个useEffect，实际执行顺序是按照在代码中定义的先后顺序来执行的
// 组件卸载前(componentWillUnmount)通过在effect中return一个函数来实现
// 代码形式
// useEffect(() => {
//     // 此处编写组件挂载之后和组件重新渲染之后执行的代码
//     ...
//     return () => {
//         // 此处编写组件即将被卸载前执行的代码
//     }
// },[deps])
// [deps]补充说明
// 1若缺省，则组件挂载，组件重新渲染，组件即将被卸载前每一次都会触发useEffect
// 2 若传值，则必须为数组，数组的内容是函数组件中通过useState自定义的变量或者是父组件传值过来的props中的
// 变量，告诉react只有数组内的变量发生变化时才会触发useEffect
// 3 若传值，但传的是空数组[]，则表示useEffect里的内容仅会在挂载完成后和组件即将被卸载前执行一次

// 若某类组件中有变量a,默认值0，当组件第一次被挂在后或组件重新渲染后，将网页标题显示为a的值
// function App () {
//     const [a,setA] = useState(0)
//     useEffect(() => {
//         document.title = `${a} + ${Math.floor(Math.random() * 100)}`
//     })
//     return (
//        <div>
//            {a}
//            <button onClick={() => {setA(a+1)}}>ADD</button>
//        </div>
//     )
// }

// 让useEffect 只在挂载后和卸载前执行一次（将第二个参数，设置为空数组，不依赖任何变量的更新所引发的组件重新渲染，
// 此组件再更新也不需要调用此useEffect）
// 需求
// 1 若某类组件中有变量a,默认值为0，当组件第一次被挂载或组件重新渲染后，将网页标题设显示为a的值
// 2 当组件第一次被挂载后执行一个自动累加器setInter，每秒a的值+ 1.为了防止内存泄露，我们在该组件即将
// 被卸载前清楚掉该累加器
// function App () {
//     const [a, setA] = useState(0)
//     // 定义第一个useEffect,专门用来处理自动累加器
//     useEffect(() => {
//         let timer = setInterval(() => {
//             setA(a => a+1) // 此处会建立一个闭包，要采用异步更新数据
//         },1000)
//     },[]) // 参数为[],告诉react以后该组件任何更新引发的重新渲染都与此effect无关
//
//     // 定义第2个useEffect，专门用来处理网页标题更新
//     useEffect(() => {
//         document.title = `${a} + ${Math.floor(Math.random() * 100)}`
//     })
//     return (
//         <div>{a}</div>
//     )
// }
// 性能优化
// 若一个组件中有一个自定义变量obj，obj有两个属性a,b,当a发生变化时，网页标题也跟着a变化
function UseEffect () {
    const [obj,setObj] = useState({a:0,b:0})
    useEffect(() => {
        document.title = `${obj.a}`
    },[obj.a])
    return (
        <div>
            <p>{JSON.stringify(obj)}</p>
            <button onClick={() => {setObj({...obj,a:obj.a+1})}}>a+1</button>
            <button onClick={() => {setObj({...obj,b:obj.b+1})}}>b+1</button>
        </div>
    )
}
export default UseEffect;
